home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / lang / fpcsrc.lha / fpc / compiler / aopt386.inc < prev    next >
Text File  |  1998-09-24  |  55KB  |  1,315 lines

  1. {
  2.     $Id: aopt386.inc,v 1.1.1.1 1998/03/25 11:18:12 root Exp $
  3.     Copyright (c) 1993-98 by Florian Klaempfl and Jonas Maebe
  4.  
  5.     This include file contains the reloading optimizer for i386+
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  ****************************************************************************
  22. }
  23.  
  24.  
  25. {$Define OptimizeMovs}
  26.  
  27. Type    TwoWords = Record
  28.             Word1, Word2: Word
  29.         End;
  30. Function Reg32(Reg: TRegister): TRegister;
  31. {Returns the 32 bit component of Reg if it exists, otherwise Reg is returned}
  32. Begin
  33.   Reg32 := Reg;
  34.   If (Reg >= R_AX)
  35.     Then
  36.       If (Reg <= R_DI)
  37.         Then Reg32 := Reg16ToReg32(Reg)
  38.         Else
  39.           If (Reg <= R_BL)
  40.             Then Reg32 := Reg8toReg32(Reg);
  41. End;
  42.  
  43. Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
  44. Begin {checks whether Ref contains a reference to Reg}
  45.   Reg := Reg32(Reg);
  46.   RegInRef := (Ref.Base = Reg) Or (Ref.Index = Reg)
  47. End;
  48.  
  49. Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
  50. {checks if Reg is used by the instruction p1}
  51. Var TmpResult: Boolean;
  52. Begin
  53.   TmpResult := False;
  54.   If (Pai(p1)^.typ = ait_instruction) Then
  55.     Begin
  56.       Case Pai386(p1)^.op1t Of
  57.         Top_Reg: TmpResult := Reg = TRegister(Pai386(p1)^.op1);
  58.         Top_Ref: TmpResult := RegInRef(Reg, TReference(Pai386(p1)^.op1^))
  59.       End;
  60.       If Not(TmpResult) Then
  61.         Case Pai386(p1)^.op2t Of
  62.           Top_Reg:
  63.               if Pai386(p1)^.op3t<>Top_reg
  64.                 then TmpResult := Reg = TRegister(Pai386(p1)^.op2)
  65.                 else TmpResult := longint(Reg) = twowords(Pai386(p1)^.op2).word1;
  66.           Top_Ref: TmpResult := RegInRef(Reg, TReference(Pai386(p1)^.op2^))
  67.         End;
  68.       If Not(TmpResult) Then
  69.         Case Pai386(p1)^.op3t Of
  70.           Top_Reg: TmpResult := longint(Reg) =twowords(Pai386(p1)^.op2).word2;
  71.           Top_none:;
  72.           else
  73.              internalerror($Da);
  74.        End
  75.     End;
  76.   RegInInstruction := TmpResult
  77. End;
  78.  
  79. Procedure ReloadOpt(AsmL: PaasmOutput);
  80.  
  81. Const MaxCh = 3;
  82.  
  83.       {content types}
  84.       con_Unknown = 0;
  85.       con_ref = 1;
  86.       con_const = 2;
  87.       con_symbol = 3;
  88.  
  89. Type TChange = (C_None,
  90.                 C_EAX, C_ECX, C_EDX, C_EBX, C_ESP, C_EBP, C_ESI, C_EDI,
  91. {                C_AX,  C_CX,  C_DX,  C_BX,  C_SP,  C_BP,  C_SI,  C_DI,
  92.                 C_AL,  C_CL,  C_DL,  C_BL,
  93.                 C_AH,  C_CH,  C_BH,  C_DH,
  94.                 C_DEFAULT_SEG, C_CS, C_DS, C_ES, C_FS, C_GS, C_SS,
  95. }                C_Flags, C_FPU,
  96.                 C_Op1, C_Op2, C_Op3,
  97.                 C_MemEDI);
  98.  
  99.      TAsmInstrucProp = Record
  100.                          NCh: Byte;
  101.                          Ch: Array[1..MaxCh] of TChange;
  102.                        End;
  103.  
  104.      TContent = Record
  105.                   StartMod: Pointer; {start and end of block instructions that defines the
  106.                                           content of this register; If Typ = con_const, then
  107.                                           Longint(StartMod) = value of the constant)}
  108.                    State: Word; {starts at 0, gets increased everytime the register is modified}
  109.                    NrOfMods: Byte;
  110. {                  ModReg: TRegister; }{if one register gets a block assigned from an other register,
  111.                                       this variable holds the name of that register (so it can be
  112.                                       substituted when checking the block afterwards)}
  113.                   Typ: Byte;        {con_*}
  114. {                  CanBeDestroyed: Boolean;} {if it's a register modified by the optimizer}
  115.                 End;
  116.  
  117.      TRegContent = Array[R_NO..R_EDI] Of TContent;
  118.      TRegFPUContent = Array[R_ST..R_ST7] Of TContent;
  119.  
  120.      TPaiProp = Record
  121.                   Regs: TRegContent;
  122. {                  FPURegs: TRegFPUContent;} {currently not yet used}
  123.                   LineSave: Longint;
  124.                   {can this instruction be removed?}
  125.                   CanBeRemoved: Boolean;
  126.                 End;
  127.  
  128.      PPaiProp = ^TPaiProp;
  129. {$IfDef TP}
  130.      TPaiPropBlock = Array[1..(65520 div (((SizeOf(TPaiProp)+1)div 2)*2))] Of TPaiProp;
  131. {$else}
  132.      TPaiPropBlock = Array[1..250000] Of TPaiProp;
  133. {$EndIf TP}
  134.      PPaiPropBlock = ^TPaiPropBlock;
  135.  
  136. Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
  137.    {MOV} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  138.  {MOVZX} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  139.  {MOVSX} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  140.  {LABEL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  141.    {ADD} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  142.   {CALL} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  143.   {IDIV} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
  144.   {IMUL} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)), {handled separately, because several forms exist}
  145.    {JMP} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  146.    {LEA} (NCh: 1; Ch: (C_Op2, C_None, C_None)),
  147.    {MUL} (NCh: 3; Ch: (C_EAX, C_EDX, C_Flags)),
  148.    {NEG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  149.    {NOT} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
  150.    {POP} (NCh: 2; Ch: (C_Op1, C_ESP, C_None)),
  151.  {POPAD} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  152.   {PUSH} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  153. {PUSHAD} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  154.    {RET} (NCh: 255; Ch: (C_None, C_None, C_None)), {don't know value of any register}
  155.    {SUB} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  156.   {XCHG} (NCh: 2; Ch: (C_Op1, C_Op2, C_None)), {(will be) handled seperately}
  157.    {XOR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  158.   {FILD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  159.    {CMP} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  160.     {JZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
  161.    {INC} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
  162.    {DEC} (NCh: 2; Ch: (C_Op1, C_Flags, C_None)),
  163.   {SETE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  164.  {SETNE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  165.   {SETL} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  166.   {SETG} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  167.  {SETLE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  168.  {SETGE} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  169.     {JE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  170.    {JNE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  171.     {JL} (NCh: 0; Ch: (C_None, C_None, C_None)),
  172.     {JG} (NCh: 0; Ch: (C_None, C_None, C_None)),
  173.    {JLE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  174.    {JGE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  175.     {OR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  176.    {FLD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  177.   {FADD} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  178.   {FMUL} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  179.   {FSUB} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  180.   {FDIV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  181.   {FCHS} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  182.   {FLD1} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  183.  {FIDIV} (NCh: 1; Ch: (C_FPU, C_None, C_None)),
  184.   {CLTD} (NCh: 1; Ch: (C_EDX, C_None, C_None)),
  185.    {JNZ} (NCh: 0; Ch: (C_None, C_None, C_None)),
  186.   {FSTP} (NCh: 1; Ch: (C_Op1, C_None, C_None)),
  187.    {AND} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  188.    {JNO} (NCh: 0; Ch: (C_None, C_None, C_None)),
  189.   {NOTH} (NCh: 0; Ch: (C_None, C_None, C_None)), {***???***}
  190.   {NONE} (NCh: 0; Ch: (C_None, C_None, C_None)),
  191.  {ENTER} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  192.  {LEAVE} (NCh: 1; Ch: (C_ESP, C_None, C_None)),
  193.    {CLD} (NCh: 1; Ch: (C_Flags, C_None, C_None)),
  194.   {MOVS} (NCh: 3; Ch: (C_ESI, C_EDI, C_MemEDI)),
  195.    {REP} (NCh: 1; Ch: (C_ECX, C_None, C_None)),
  196.    {SHL} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  197.    {SHR} (NCh: 2; Ch: (C_Op2, C_Flags, C_None)),
  198.  {BOUND} (NCh: 0; Ch: (C_None, C_None, C_None)),
  199.